# -*- coding: utf8 -*-

import cv2
import time
import base64
import numpy as np
from my_det import *
from loguru import logger
from od_config import *
from datetime import datetime


class http_port:
    def __init__(self):
        # 日志相关参数
        self.log = logger
        self.log_info()
        self.time_stamp = datetime.now()
        # 入参相关参数
        #self.data=data
        self.return_result = {}

    def get_result(self,data):
        try:
            self.input_specification(data)
        except Exception as e:
            self.return_result["code"] = int(100002)   # 入参错误
            self.return_result["msg"] = f"{e}"
            self.return_result["result"] = int(1)
            # 日志记录
            self.log.error('--get the request--')
            self.log.error(f"接收请求时间:{self.time_stamp}")
            self.log.error(f"业务结果:{self.return_result}")
            self.log.error(f"服务请求失败,失败时间:{datetime.now()}")
            self.log.error("--Finish--\n")
            return self.return_result
        else:
            try:
                alarm, result = self.target_predict(data)
            except Exception as e1:
                self.return_result["code"] = int(100003)  # 模型内部程序错误
                self.return_result["msg"] = f"{e1}"
                self.return_result["result"] = int(1)

                # 日志记录
                self.log.error('--get the request--')
                self.log.error(f"接收请求时间:{self.time_stamp}")
                self.log.error(f"业务结果:{self.return_result}")
                self.log.error(f"服务请求失败,失败时间:{datetime.now()}")
                self.log.exception(e1)
                self.log.error("--Finish--\n")
                return self.return_result
            else:
                if alarm:   # True 检测到完整性
                    self.return_result['code'] = int(0)
                    self.return_result["marks"] = result 
                    if len(result)>0:  # 在检测到完整性的基础上 有开始检测封堵
                        cls_list_all_target = []
                        for j in result:
                            cls_list_all_target.append(j['cls'])
                            if 'not_plugging' in cls_list_all_target:
                                self.return_result["result"] = int(1)  
                                self.return_result["message"] = "all_target,exist_not_plugging" # 照片面板拍摄完整，存在未封堵空洞  报警   result=1
                            else:
                                self.return_result["message"] = "all_target,exist_plugging" # 图片拍摄完整且封堵合格 不告警 result=0
                                self.return_result["result"] = int(0)  
                    else:  
                        self.return_result["marks"] = []
                        self.return_result["message"] = "all_target,no_plugging"  #  照片面板拍摄完整，未检测到封堵情况 报警 result=1
                        self.return_result["result"] = int(1)  

                    # 日志记录
                    self.log.info('--get the request--')
                    self.log.info(f"接收请求时间:{self.time_stamp}")
                    self.log.info(f"业务结果:{self.return_result}")
                    self.log.info(f"当次请求截至时间:{datetime.now()}")
                    self.log.info("--Finish--\n")
                else:  # 未检测到完整性 但继续走检测封堵
                    self.return_result['code'] = int(0)
                    self.return_result["marks"] = result
                    if len(result)>0:
                        cls_list_no_all_target = []
                        for j in result:
                            cls_list_no_all_target.append(j['cls'])
                            if 'not_plugging' in cls_list_no_all_target:
                                self.return_result["result"] = int(1)  
                                self.return_result["message"] = "not_all_target,exist_not_plugging" # 照片面板拍摄不完整，识别到未封堵空洞 报警 result=1
                            else:
                                self.return_result["result"] = int(1)  
                                self.return_result["message"] = "not_all_target,exist_plugging"  # 照片面板拍摄不完整，识别到封堵空洞 报警 result=1
                    else:
                        self.return_result["marks"] = []
                        self.return_result["message"] = "no_all_target,no_plugging"  # 照片无法识别，建议重新拍摄或转人工稽核 报警 result=1
                        self.return_result["result"] = int(1)  

                    # 日志记录
                    self.log.info('--get the request--')
                    self.log.info(f"接收请求时间:{self.time_stamp}")
                    self.log.info(f"业务结果:{self.return_result}")
                    self.log.info(f"当次请求截至时间:{datetime.now()}")
                    self.log.info("--Finish--\n")
                return self.return_result

    def target_predict(self,data):
        all_result = []
        target_result = detect_tail_fiber(image=self.image_img,model=model_all_target,minScore=data["minScore"])
        if target_result!=[]:
            for obj in target_result:
                img_tmp = self.image_img[obj[1]:obj[3], obj[0]:obj[2]]
                target_result_2 = detect_tail_fiber(image=img_tmp, model=model_plugging,minScore=data["minScore"])
                for obj_tmp in target_result_2:
                    result = {}
                    result["cls"] = obj_tmp[5]
                    result["score"] = obj_tmp[4]
                    result["axis"] = [obj_tmp[0]+obj[0], obj_tmp[1]+obj[1], obj_tmp[2]+obj[0], obj_tmp[3]+obj[1]]  #坐标返回到原图尺寸上
                    if result["score"] <= 0.99:
                        all_result.append(result)
            alarm_state = True  # 检测到完整性
        else:
            target_result_2 = detect_tail_fiber(image=self.image_img, model=model_plugging,minScore=data["minScore"])
            for obj_tmp in target_result_2:
                result = {}
                result["cls"] = obj_tmp[5]
                result["score"] = obj_tmp[4]
                result["axis"] = [obj_tmp[0], obj_tmp[1], obj_tmp[2], obj_tmp[3]]  #坐标直接就在原图尺寸上
                if result["score"] <= 0.99:
                    all_result.append(result)
            alarm_state = False  # 未检测到完整性
        return alarm_state,all_result


    def input_specification(self,data):
        assert "image" in data.keys() and isinstance(data["image"], str) and len(data["image"]) > 0, "image格式错误"
        b_image = base64.b64decode(data["image"])
        b_image_array = np.fromstring(b_image, np.uint8)
        self.image_img = cv2.imdecode(b_image_array, cv2.COLOR_BGR2RGB)

        self.minScore: float = data["minScore"] if "minScore" in data.keys() else 0.5  # 默认是0.5
        assert isinstance(self.minScore, float), "minScore参数格式错误"

    def log_info(self):
        # 日志相关
        self.log.remove()
        self.log.add(
            f"{INFO_LOG_PATH}/{INFO_LOG_NAME}_{time.strftime('%Y-%m-%d')}.log",
            level="INFO",
            filter=lambda record: record["level"].name == "INFO",
            rotation="00:00",  # 每分钟轮换日志文件
            encoding="utf8",
            compression=None,  # 压缩归档旧日志文件
            retention="180 day",  # 保留最近180天的日志文件
            format="{time:YYYY-MM-DD HH:mm:ss.SSS} | {level} | (file:{file.name}:{line}) {message}",
            backtrace=True,  # 记录完整的异常堆栈跟踪信息
            diagnose=True  # 在日志中显示更多的诊断信息
        )
        self.log.add(
            f"{ERROR_LOG_PATH}/{ERROR_LOG_NAME}_{time.strftime('%Y-%m-%d')}.log",
            level="ERROR",
            filter=lambda record: record["level"].name == "ERROR",
            rotation="00:00",  # 每分钟轮换日志文件
            encoding="utf8",
            compression=None,  # 压缩归档旧日志文件
            format="{time:YYYY-MM-DD HH:mm:ss.SSS} | {level} | (file:{file.name}:{line}) {message}",
            retention="180 day",  # 保留最近180天的日志文件
            backtrace=True,  # 记录完整的异常堆栈跟踪信息
            diagnose=True  # 在日志中显示更多的诊断信息
        )


